package org.srtc.infopub.tools;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * �ṩ����XML�Ľӿ��У�
 * 
 * ��1���õ���ڵ�: public Element rootElement();
 * ��2���õ�����Ҷ�ӽڵ�ȫ·������б?public void baseInfo();����info��
 * ��3������father�ڵ�ĺ��ӽڵ���tag��ΪtagName�Ľڵ㣺public Node getNodeByTag(Node father, String tagName);
 * ��4���õ�NodeList��Ϊelement�Ľڵ㼯�ϣ�public ArrayList<Element> getElementList(NodeList list);
 * ��5���õ�itemNode�ڵ��attribute�������Ӧ��ֵ��public String getAttributeName(Element itemNode, String attribute);
 * ��6���õ�father�ڵ����Ӧ������Ҷ�ӣ�public void getAllLeavesInfo(Node father, ArrayList<Element> leavesInfo);
 * ��7���õ����нڵ��name-shortName, code-shortName�ĵ��ţ�public void createRevertMaps(Node n);
 * 
 * @author yinlei
 *
 */


public class TestXML {
	
	/**
	 * ����XML����ĵ�����
	 */
	private Document doc;
	
	/**
	 * ����Ҷ�ӽڵ�ȫ·������б�
	 */
	private HashMap<String, String> info;
	
	/**
	 * ���нڵ����Ӧ��Ҷ�ӽڵ�
	 */
	public HashMap<String, ArrayList<String>> quiteTable;
	
	/**
	 * Ϊ�˼��ٲ�ѯ������name-shortName���ű�
	 */
	public HashMap<String, String> nameShort;
	
	/**
	 * Ϊ�˼��ٲ�ѯ������code-shortName���ű�
	 */
	public HashMap<String, String> codeShort;
	
	
	public TestXML(String filename) {
		info = new HashMap<String, String>();
		nameShort = new HashMap<String, String>();
		codeShort = new HashMap<String, String>();
		quiteTable = new HashMap<String, ArrayList<String>>();
		
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
			DocumentBuilder db;			
			db = dbf.newDocumentBuilder();			
			doc = db.parse(filename);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public HashMap<String, String> getInfo() {
		return info;
	}


	/**
	 * ���ظ�XML�ĸ�ڵ�
	 * @return ��ڵ�Element����
	 */
	public Element rootElement() {
		Element root = doc.getDocumentElement();
		return root;
	}
	
	
	/**
	 * ����father�ڵ�ĺ��ӽڵ���tag��ΪtagName�Ľڵ�
	 * @param father
	 * @param tagName
	 * @return
	 */
	public Node getNodeByTag(Node father, String tagName) {
		if (father == null) {
			return null;
		}
		NodeList nList = father.getChildNodes();
		if (nList != null) {
			for (int i = 0; i < nList.getLength(); i++) {
				if (nList.item(i).getNodeName().equals(tagName)) {
					return nList.item(i);
				}
			}
		}
		return null;
	}
	
	
	/**
	 * �õ�NodeList��Ϊelement�Ľڵ㼯��
	 * @param list
	 * @return
	 */
	public ArrayList<Element> getElementList(NodeList list) {
		ArrayList<Element> elements = new ArrayList<Element>();
		for (int i = 0; i<list.getLength(); i++) {
			if (list.item(i).getNodeType() == Node.TEXT_NODE) {
				continue;
			}
			elements.add((Element)list.item(i));
		}
		return elements;
	}
	
	
	/**
	 * �õ�itemNode�ڵ��attribute�������Ӧ��ֵ
	 * @param itemNode
	 * @return
	 */
	public String getAttributeName(Element itemNode, String attribute) {
		return itemNode.getAttribute(attribute);
	}
	
	
	/**
	 * �õ��ڵ�n�İ�att����ֵ׷�ӵ�ȫ·��
	 * @param n
	 * @param att ��ʲô����ֵ׷��ȫ·��
	 * @return
	 */
	public String getWholeShortName(Node n, String att) {
		Node dataNode = getNodeByTag(rootElement(), "data");
		Node shortNameNode = getNodeByTag(rootElement(), att);
		
		String wholeName = "";
		
		if (n == null) {
			return null;
		}
		if (n.getNodeType() == Node.ELEMENT_NODE) {
			while (dataNode != n) {
				wholeName = getAttributeName((Element)n, att) + "." + wholeName;
				n = n.getParentNode();
			}
			
			wholeName = shortNameNode.getTextContent() + "." + wholeName;
			
			return wholeName;
		}
		return null;
	}
	
	
	/**
	 * �õ�father�ڵ����Ӧ������Ҷ��
	 * @param father
	 * @param leavesInfo
	 */
	public void getAllLeavesInfo(Node father, ArrayList<Element> leavesInfo) {		
		if (father == null || father.getNodeType() == Node.TEXT_NODE) {
			return;
		}
		
		NodeList children = father.getChildNodes();
		ArrayList<Element> eList = getElementList(children);
		if (eList.size() == 0) {
			leavesInfo.add((Element)father);
			return;
		}
		for (int i = 0; i<eList.size(); i++) {
			getAllLeavesInfo(eList.get(i), leavesInfo);
		}
	}
	
	
	/**
	 * �������Ҷ��ȫ·������б�(��shortName��ȫ·��)
	 */
	public void baseInfo() {
		Element e = null;
		if ((e = rootElement()) != null) {
			Node n = getNodeByTag(e, "data");
			if (n == null) return;
			
			ArrayList<Element> elements = new ArrayList<Element>();
			getAllLeavesInfo(n, elements);
			for (int i = 0; i<elements.size(); i++) {
				info.put(getWholeShortName(elements.get(i), "code"), elements.get(i).getAttribute("dataType"));
			}
		}
	}
	
	
	/**
	 * �任�û�query
	 * @param query �û�query
	 * @param type �û���������
	 * @return ����ת��ΪshortName���ִ�
	 */
	public String transQuery(String query, int type) {
		String shortName = "";
		
		if (type == 1) {
			shortName = nameShort.get(query);
		}
		
		if (type == 2) {
			shortName = codeShort.get(query);
		}
		
		return shortName;
	}
	
	
	/**
	 * �õ��������ű�
	 * @param n
	 */
	public void createRevertMaps(Node n) {
		
		if (n.getNodeType() != Node.ELEMENT_NODE) {
			return;
		}
		
		NodeList list = n.getChildNodes();
		ArrayList<Element> eList = this.getElementList(list);
		if (eList.size() == 0) {
			String shortName = this.getWholeShortName(n, "shortName");
			String name = this.getWholeShortName(n, "name");
			String code = this.getWholeShortName(n, "code");
			
			nameShort.put(name, shortName);
			codeShort.put(code, shortName);
			return;
		}
		
		for (int i = 0; i<eList.size(); i++) {
			String shortName = this.getWholeShortName(n, "shortName");
			String name = this.getWholeShortName(n, "name");
			String code = this.getWholeShortName(n, "code");
			
			nameShort.put(name, shortName);
			codeShort.put(code, shortName);
			createRevertMaps(eList.get(i));
		}
	}
	
	
	/**
	 * �õ�e�ڵ����µ����нڵ����Ӧ��Ҷ�ӽڵ�
	 * @param e
	 */
	public void quiteTable(Element e) {
		if (e.getNodeType() != Node.ELEMENT_NODE) {
			return;
		}
		
		ArrayList<Element> arr = this.getElementList(e.getChildNodes());
		if (arr.isEmpty()) {
			ArrayList<Element> es = new ArrayList<Element>();
			ArrayList<String> strs = new ArrayList<String>();
			
			this.getAllLeavesInfo(e, es);
			for (int i = 0; i<es.size(); i++) {
				strs.add(this.getWholeShortName(es.get(i), "code"));
			}
			this.quiteTable.put(this.getWholeShortName(e, "code"), strs);
			
			return;
		}
		
		for (int i = 0; i<arr.size(); i++) {
			ArrayList<Element> es = new ArrayList<Element>();
			ArrayList<String> strs = new ArrayList<String>();
			
			this.getAllLeavesInfo(arr.get(i), es);
			for (int j = 0; j<es.size(); j++) {
				strs.add(this.getWholeShortName(es.get(j), "code"));
			}
			this.quiteTable.put(this.getWholeShortName(arr.get(i), "code"), strs);
			
			quiteTable(arr.get(i));
		}
	}
	
	
	public void getQuiteTable() {
		ArrayList<String> arr = new ArrayList<String>();
		
		this.baseInfo();
		Set<String> set = this.getInfo().keySet();
		Iterator<String> it = set.iterator();
		
		while (it.hasNext()) {
			String str = it.next();
			arr.add(str);
		}
		
		quiteTable.put(this.getNodeByTag(this.rootElement(), "code").getTextContent() + ".", arr);
		
		this.quiteTable((Element)getNodeByTag(rootElement(), "data"));
	}
	
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		TestXML tXML = new TestXML("gzmxx.xml");

		tXML.getQuiteTable();
		System.out.println(tXML.quiteTable);
	}

}
